- web6047 - (2021/09/10(金) 現在、システム調整中のため、一部の表示がおかしいかもしれません)







homepage6047 2019年 1月

プログラミングやRPG(作るほう)が好きな人の日記

2019/1/30(水)

H8マイコン 3052F を初めて使ってみる(LAN開発キット)-[kumitate]

マイコンというのは、パソコンのCPUと同じようなもので、炊飯器や、高機能な湯沸かし器などいろいろな家電の中に入っていて、プログラムで家電を便利に操作してくれる電子回路部品です。電子工作では好きなプログラムをマイコンに書き込んで、創意工夫でいろいろなものを作ることができます。

fig.
▲H8マイコン3052F

秋月電子通商で販売されている、日立製作所のH8マイコン3052Fを載せたCPU(マイコン)ボードです。

ひさしぶりにはんだ付け作業を行いました。

左の画像リンクをクリックすると 画像を拡大 します。



fig.
▲液晶ディスプレイ

LAN機器の開発キットというセットで、液晶ディスプレイ(文字表示のみ)もついています。

左の画像リンクをクリックすると 画像を拡大 します。



fig.
▲LAN機器開発キット

上記のCPU(マイコン)ボードと液晶ディスプレイを、LAN機器の本体に装着して、電源を入れたところ。

LAN機器開発キットは、マイコンボード、液晶ディスプレイ、LAN機器本体の3点セットで8200円。

左の画像リンクをクリックすると 画像を拡大 します。



fig.
▲LAN機器として認識

自室のルーターにLANケーブルで接続したところ。液晶ディスプレイに接続を知らせる情報が表示されています。

左の画像リンクをクリックすると 画像を拡大 します。



fig.
▲PINGコマンドに応答した

同じネットワーク上のパソコンからそのLAN機器のIPアドレスへ向けてPINGコマンドを打つと、このように返事が返ってきました。(私もPINGコマンドを使うのはあまり慣れているわけではありません)

左の画像リンクをクリックすると 画像を拡大 します。



どうしてLAN機器開発キットなのかというと、もうすぐ国家資格の「電子機器組立て1級」の資格取得の時期なんですが、ぜんぜんやる気がわいてこないんです。

そこで、自分への「てこ上げ」として、とりあえず何か電子工作をやってみようと思ったわけです。

で、私が失業してハローワークの電子回路エンジニア科を受講したときにもらった教科書(「C言語による組込み制御入門講座」という本があって、その本がまだ(長年)未着手だったので、これをやろうと思いました。

その本で取り扱っているマイコンが日立製作所H8マイコン3052Fだったというわけです。秋月電子通商で同マイコンを探したところ、手ごろだったのがLAN開発キットでした。

H8/3052Fはもうだいぶ古いマイコンと言われていますが、工業(産業)の世界では3052と同じシリーズで型番の少し違うものがまだ使われているって話を最近聞きました。枯れたシステム(完成されたシステム)では、わざわざ新しいものに変えることはなく、そのままの材料で作るのがベストだということでしょう。

古いマイコンとはいえ、マイコンとして完成されており、まだ使えるのに、古いというだけで「使えない」とされるのはもったいない気がします。でも新しいマイコンが次々と出てきて、古いマイコンの開発環境が更新されないまま古くさくなり、サポートも減って、その辺が「使えない」となってしまうんでしょう。


仕事でどことなく関係しているので、面白いと思っています(やる気が出始め)


2019/1/14(月) 3連休3日目

上のメニューの aboutThisWebsite.html の「感想、意見 送信フォーム」でエラー表示(Internal Server Error)になっていましたが修正しました。


2019/1/12(土) 3連休1日目 

Movie + Canvas -[javascript]

KONAMI のシューティングゲーム「グラディウスV」のスーパープレイのYouTube動画に衝撃を受けました。ゴージャスってこういうのを言うんだなと。

で、背景に動画(?)を使っているのを見て、動画(VIDEOタグ)と JavaScript の CANVAS を重ねられないかなと思ってやってみようと思いました。

それは結果としてできたんですが、それ以前に大事なことがあると思いました。

スーパープレイ動画の開始12秒から17秒までの5秒のあいだに、背景のアングルが大きく ぐるっ と変わるんですが、このカメラの魅力的な動き、普通はどうやるのか見当つかないと思うんです。

背景に動画を使うようなカラクリの話よりも、ダイナミックで魅力的な表現について説明するほうがニーズが高く、そこをほったらかしにするのは NG のような気がしました。

これから説明しますので、なるほどそういうことか、とわかってもらえれば幸いです。

動画と CANVAS を重ねる話はそのあとでしています。


(自機の当たり判定なし、無限ループ)


↑↓←→ : 移動(Move)、 z : 攻撃(Attack)、背景のMP4は1.57MB


背景のアングルが大きく ぐるっ と変わる。どうやるの?

fig.
▲Shade3Dの画面

一般の こういうのをあまりやらない人にもわかるように説明したいと思います。

3DCGのレンダリングソフトの Shade3D を使いますが、「カメラワーク」の話なので、ほかのソフトでもやることは同じだと思います。

2020年11月14日追記:改めて自分でこの説明を読み直してみたところ、ちょっと Shade3D のしくみの話が多く、しかもわかりにくいと思いました。

ちなみに、Shade3Dは去年の暮れあたりから、通常の販売をすべてやめて、サブスクリプション(年ごとに支払いを繰り返す)になってしまい、ホビーユーザーは利用しづらくなりました。現在はパッケージの店頭売れ残りがあればラッキー(このリンクはAmazonで検索します)といった感じです。残念。

左の画像リンクをクリックすると 画像を拡大 します。




説明ステップ 1/4

主に動画を説明材料にして説明していきます。

しかし、まず最初は動画ではなく、「カメラを動かさない状態」を見ていただくと、こんな感じです。

編集中:

レンダリング結果:


上記 「編集中:」の画像の下のほうの線画の赤い物体が「カメラ」で、図の上のほうを向いている状態です。(下図に抜粋)

この状態からカメラワークのアニメを順番に加えていきます。


説明ステップ 2/4

リング内を旋回するアニメを加えます。

カメラの位置だけを変更するアニメであり、首を振るアニメではないので、カメラは常に図の上を見ながら、リング内を回ります(下図赤矢印)。

編集中:


レンダリング結果:

(MP4: 600KB)


リング内を回るのは、上図の「編集中:」の動画の右側のツリー表示で、「①パス(カメラ旋回移動用)」というフォルダの下に「カメラ」を入れているからそのように回ります。(下図に抜粋)

(※細かいアニメの設定はこのような画面で別途行います)

こういう単純な回転だけなら難しいことはないと思います。


説明ステップ 3/4

今度はカメラはリングの中心を見ながら、リング内を回ります。

(このレンダリング結果ならゲームの背景にしても良さそうです)

編集中:


レンダリング結果:

(MP4: 556KB)

上図の「編集中:」の動画の右側のツリー表示を見てもらうと、「①パス(…)」のフォルダの下にさらに「②回転(中心注視回転用)」というフォルダを作っているのがわかると思います。 (下図に抜粋)

これで、「カメラ」はリング内を旋回(いわゆる公転)しつつも、中心を見るように自転もしている、というアニメになります。

なお、下の自転だけにした動画を見てもらうと、「②回転(中心注視回転用)」によって自転だけしている というのがわかると思います。

(MP4: 1.77MB)


リング内を旋回して、自転もする。

これもまぁ、ふつうの回転であって、難しいことはないと思います。

ではグラディウスVみたいに、背景のアングルが大きく ぐるっ と変わるのはどうやるんでしょうか。

 リングの中心を見ていない、こういうアングルですね。


説明ステップ 4/4

カメラがリングの左上くらい(下図)まで回ってきたところで、向いている方向をリングの中央ではなく、回ってきた道すじのほうを見るように(濃い青の矢印)アニメを追加します。

編集中:


レンダリング結果: (目的達成)

(MP4: 728KB)

上図の「編集中:」の動画の右側のツリー表示を見てもらうと、フォルダ「①パス(…)」によるリング内旋回と、その下の「②回転(…)」で自転を行い、さらにその下に「③回転(左右首振り用)」というフォルダを作っていて、その下に「カメラ」があります。(下図に抜粋)


その「③回転(左右首振り用)」フォルダは「ある場所まで来たらちょっと首を後ろに振ってくれ」というような設定を別途行っています。正直ちょっとわかりづらい画面だと思うんですが下図のように設定しています。


ちょっと難しいですかね。これで上の「レンダリング結果:(目的達成)」のような動画になります。

つまり、今までの説明を要約すると「カメラの位置を変更(リング内を旋回)しつつ、ある時点でカメラの向いている向きをちょっと変えるんだ」ということです。一言で言うと「カメラの首を振れば良い」です。

わざわざここまで動画と画像を駆使して説明することもないんですが、私が一人で分かっていてこのページを見ている皆さんが「どうやるんだろう」と思いつつも分からないでいるというのは一番力を入れて解決すべきことだと思ったので頑張って説明しました。


Movie + Canvas 大まかな実現方法 (これがもともとの本題):

つまり、単純に重ねればよいということです。


新しいウィンドウで実行 新しいウィンドウでMP4を表示(MP4: 1.57MB)  

一連のファイルをまとめたZIP(1.94MB)です。おてもとで動かせます。
このシューティングゲームのプログラムリストです。
[programlist.cgi]
file not found.1
current dir:[]
path(UTF8):[/home/web6047/www/cgi-bin/prj/20190111-javascript%EF%BC%8FJavadiusV/javascript.html]
path(FSYS):[/home/web6047/www/cgi-bin/prj/20190111-javascript%EF%BC%8FJavadiusV/javascript.html]
[^^com.programlist "/cgi-bin/prj/20190111-javascript%EF%BC%8FJavadiusV/javascript.html" -css:codeNormal -indent:relative^^
^^com.programlist "/cgi-bin/prj/20181231-SVC - snapshot20190102-1/javascript.html" -css:codeNormal -indent:relative^^
^^com.programlist "/webappsrccheck.html" -css:codeNormal -indent:relative^^
^^com.programlist "/webappsrccheck.html" -css:codeNormal -indent:relative^^
^^com.programlist "/webappsrccheck2.html" -css:codeNormal -indent:relative^^
^^com.programlist "/webappsrccheck2.html" -css:codeNormal -indent:relative^^
]

「グラディウスV」でシューティングゲームの背景を動画(…ではなくリアルタイムのレンダリング?)にしてしまうなんてコナミの開発者の方はすごいことを考えたもんですね。

動画とゲームを融合させるというのはもとはスクエア・エニックスがファイナルファンタジー7で始めたことで(動画の最後の画面でそのままゲーム開始される)、パラサイトイヴ2では動画の再生中に動画の中のパースに合わせてキャラを操作することができたとか。


2019/1/5(土) 年末年始休み 9日目/10日

iTunes で映画「Mission:Impossible Fallout」を観ました -[eiga]

全体的に出来が良い気がします。

シリーズを面白い順に並べると、

1 → 6(今作) → 5(シンジケート) → 4(クレムリン爆破) → 3(ラビットフット) → 2(キメラ) です。

1作目が一番面白くて、2作目で大きく落として、シリーズを進めるごとに良くなってるみたいです。

でもそれでも今作も私が求めている1作目の痛快さがなく、普通のアクション映画っていう印象がぬぐえないかな。

良いところを言うと、雪山でヘリが転がるとき、転がってる最中のヘリの機内の はげしい様子がスゴくて、どうやって撮影しているんだろうと思いました。

iTunesサイト 「ミッション:インポッシブル フォールアウト」


2019/1/2(水) 年末年始休み 6日目/10日

エレガントなプログラム -[program]

fig.
▲プログラミングの楽しみ

プログラミングは何が楽しいかというと、「自分の思った通りに動いたとき何より楽しい!」とよく言われていると思います。

「こんなプログラムを作ろう」と思ってスタートし、プログラミングを行い、目的の結果が得られたらゴールです。

左図は、左下の青い S がプログラムのスタートで、右上の赤い G がプログラムのゴールです。S と G を結ぶ黄色い線がプログラムの出来栄えを表しており、S から G へ向かって直線であるほど、望ましいプログラムです。

目的のプログラムができたら(図で言うと G に到達したら)結構うれしくて、「やった!」と思います。



fig.
▲遠回りなプログラム

でも、目的のプログラムができたとしても、処理が遠回りだったり、処理が重かったりすると、一応できてはいるんだけど、もっといい方法があるんじゃないの?という出来栄えの場合もあります。

図で言うと、直線ではなく、湾曲しています。

それでもゴールに到達していれば、感動の宝物だったりするんですが。



fig.
▲自分にはできない?

または、志し半ばにして、目的の結果が得られず挫折する場合もあります。

図では、黄色い線が G に到達していません。

自分には出来ないんだ、なんて思って悲しくなることもあります。

ここで負けずに食い下がれるかどうかが、分かれ道かな?

しかしこういうものは あなた次第、だけではなく、これを読んでいる皆さんの周囲にいる 教える人の力量にもかかっています。



fig.
▲これがベストな状態

まぁ、最高のプログラムでなくても、ほどほどの出来栄えで目的の結果が得られれば、だいたい良いと思います。これがベストだと思います。

図で言うと、多少湾曲していても、まずまず、直線に近い感じです。

図は一本の線ですが、どんなプログラムにするかは人それぞれで、それがまた楽しいところでもあります。



fig.
▲プログラミングのもう1つの楽しみ

いかにして より良いエレガントなプログラムにするか。

もっといい方法は…と四六時中考えて、仕事中にでも ふとしたことで「そうだ!その手があったか!」と思うと、そのあとは一日ウキウキとします。

プログラムがエレガントになる、というのは、ゴールに到達したときと同じような感動であり、プログラミングのもう1つの楽しみです。

「プログラミング 何が 楽しい」をキーワードにしてWEB検索してみると、「デバッグが難解パズルを解くみたいで楽しい」とか「他人のコードを見るとその人の思想を垣間見ることができて楽しい」とか「自分で書いたコードがどんどん動いていくのでだんだん楽しくなってきて…」とか「自分で作ったものが自分のiPhoneで動いて、作ったものが動いていることを実感できて楽しい」とか、人それぞれいろいろあるみたいです。

よりエレガントにするにはプログラムの手段をいろいろ知っている必要があると思います。なので、とてもやりがいのある分野じゃないかなと思います。



2019/1/1(火) 年末年始休み 5日目/10日

アニメーションプログラムの例 -[javascript]

fig.
▲アニメーション

アニメーションプログラムの1つの形です。

ポーズからポーズへと遷移します。

左の画像リンクをクリックすると、新しいウィンドウを開いてJavaScriptを実行します。

赤、緑、青の3つのDIV要素が、4種類の配置(ポーズ)をつぎつぎと切り替えます。

ポーズとポーズのあいだは座標の増減で補間され、アニメーションになっています。

ポーズごとに時間の指定を変えているので、動きの速さに違いがあります。


良いところ:

良くないところ:

そのプログラムリスト:

<!DOCTYPE html><!--ESCAPEPROCESS-->

<head>

<meta content="text/html; charset=UTF-8" http-equiv="content-type">

<title>UntitledHomepage6047JavaScript</title>

<script>


console.clear();

console.log( "=============== script ==============" );


//単位を除去する。(Delete Unit)

function DU( value ) { return Number( value.replace( "px", "" ) ); }


function onloadx() {


timerMS = 50;


//各ポーズの作成

pose1 = new Pose( "pose1", 500 );

pose1.add( document.getElementById( "red" ).style, "left", 500 ),

pose1.add( document.getElementById( "green" ).style, "left", 500 ),

pose1.add( document.getElementById( "green" ).style, "top", 500 ),

pose1.add( document.getElementById( "blue" ).style, "top", 500 ),

/*

各ポーズのおおまかなデータ構造

pose1 ... new Pose

pose1.acts ... new Array

0 ... new Act HTML要素"red"のstyleのメンバ変数leftについて現在値から500まで値を変化させる

1 ... new Act 同様

2 ... new Act 同様

3 ... new Act 同様

pose2



*/


pose2 = new Pose( "pose2", 1300 );

pose2.add( document.getElementById( "red" ).style, "top", 500 ),

pose2.add( document.getElementById( "green" ).style, "top", 0 ),

pose2.add( document.getElementById( "blue" ).style, "left", 500 ),


pose3 = new Pose( "pose3", 500 );

pose3.add( document.getElementById( "red" ).style, "left", 0 ),

pose3.add( document.getElementById( "red" ).style, "top", 0 ),

pose3.add( document.getElementById( "green" ).style, "left", 0 ),

pose3.add( document.getElementById( "green" ).style, "top", 500 ),

pose3.add( document.getElementById( "blue" ).style, "top", 0 ),


pose4 = new Pose( "pose4", 1300 );

pose4.add( document.getElementById( "red" ).style, "left", 0 ),

pose4.add( document.getElementById( "red" ).style, "top", 0 ),

pose4.add( document.getElementById( "green" ).style, "left", 0 ),

pose4.add( document.getElementById( "green" ).style, "top", 0 ),

pose4.add( document.getElementById( "blue" ).style, "left", 0 ),

pose4.add( document.getElementById( "blue" ).style, "top", 0 ),


//シーケンス作成 (あるポーズを取ったら、次のポーズへ向かって値を遷移させる)

pose1.nextPose = pose2;

pose2.nextPose = pose3;

pose3.nextPose = pose4;

pose4.nextPose = pose1;


currentPose = pose1;

currentPose.ready();


timerID = setInterval( frame, timerMS );

}

//1フレーム分の動作

function frame() {

currentPose.frame();

//check. ポーズが完了したら次のポーズへ

if( currentPose.endFlg ) {

currentPose = currentPose.nextPose;

currentPose.ready();

}

}



//クラス1: 1つのポーズを形作る、Actの集合

function Pose( title, time ) {

/*

time この時間内にアニメーションを終わらせる

*/

this.title = title;

this.time = time;

this.acts = new Array();

this.endFlg = false;

}

//actsにActを追加する

Pose.prototype.add = function( object, objectMember, endValue ) {

this.acts.push( new Act( object, objectMember, endValue, this.time ) );

}

//1フレーム分の動作

Pose.prototype.frame = function() {


//すべてのActが終了したら、このポーズは完了

var allEnd = true;

for( var i = 0; i < this.acts.length; i++ ) {

var act = this.acts[ i ];

if( ! act.endFlg ) {

allEnd = false;

break;

}

}

if( allEnd ){

this.endFlg = true;

return;

}


//Actを進行

for( var i = 0; i < this.acts.length; i++ ) {

this.acts[ i ].frame();

}

}

//現在の状況(DOMの現在値)に合わせて、初期化

Pose.prototype.ready = function() {

console.log( this.title + " へ" );

for( var i = 0; i < this.acts.length; i++ ) {

this.acts[ i ].ready();

}

this.endFlg = false;

}



//クラス2: オブジェクトのあるメンバ変数を、現在値からendValueまで、time時間かけて遷移させる

function Act( object, objectMember, endValue, time ) {

this.object = object;

this.objectMember = objectMember;

this.endValue = endValue;

this.time = time;

this.direction = 0;

this.step = 0;

this.endFlg = false;

}

//現在の状況に合わせて、初期化

Act.prototype.ready = function() {

//現在値から目標値までの距離

var len = this.endValue - DU( this.object[ this.objectMember ] );

//check.すでに到達

if( len == 0 ) {

this.endFlg = true;

return;

}

this.direction = len > 0 ? 1 : -1;

this.step = len / ( this.time / timerMS );

this.endFlg = false;

}

//1フレーム分の動作

Act.prototype.frame = function() {

this.increment();

}

//進行

Act.prototype.increment = function() {

if( this.object[ this.objectMember ].match( /px/ ) )

this.object[ this.objectMember ] = ( DU( this.object[ this.objectMember ] ) + this.step ) + "px";

else

this.object[ this.objectMember ] += this.step;


this.endFlg = DU( this.object[ this.objectMember ] ) * this.direction >= this.endValue * this.direction;

//check.終了の場合は、余分な移動を補正する

if( this.endFlg ) {

if( this.object[ this.objectMember ].match( /px/ ) )

this.object[ this.objectMember ] = this.endValue + "px";

else

this.object[ this.objectMember ] = this.endValue;

}

}



</script>

<style>

</style>

</head>

<body onload="onloadx();" style="background-color:white;">


<div id="red" style="

position : absolute;

background-color : red;

left : 0px;

top : 0px;

width : 32px;

height : 32px;

opacity : .5;

"></div>

<div id="green" style="

position : absolute;

background-color : green;

left : 0px;

top : 0px;

width : 32px;

height : 32px;

opacity : .5;

"></div>

<div id="blue" style="

position : absolute;

background-color : blue;

left : 0px;

top : 0px;

width : 32px;

height : 32px;

opacity : .5;

"></div>


</body>

</html>


(このプログラムは著作権を特に主張しませんので気に入ったら自由にコピペして使ってください)


Google Playで映画「シャッフル」を観ました -[eiga]

(2007年アメリカ/サスペンス/1:36/一般評価★★★☆☆/私評価★★★★

人間ドラマとしてしっかりしているし、SF(起こりそうも無い事を起こりそうに描いたもの)としても楽しめると思います。人間ドラマを見て泣いたことがある人は、この映画はおススメです。埋もれた名作だと思ったんだけど、私が一人でそう思っているだけなのかな。

Google Play 「シャッフル」



webappsrcの確認

1. %%com.webapp.src:/webappsrccheck.html%%
と記述した場合

webapps/src/default.cssのスタイル指定が効く
<!DOCTYPE html><!--ESCAPEPROCESS-->

<head>

<script>

function onloadx() {

//一般関数

console.log( "文字列" );

}

function Class1() {

//クラス

console.log( "文字列" );

}

Class1.prototype.method1 = function() {

//メソッド

console.log( "文字列" );

}

</script>

</head>

<body onload="onloadx();" style="">

Hello world!<BR>

</body>

</html>



2. <code>
%%com.webapp.src:/webappsrccheck.html%%
</code>
と記述した場合

このファイルのcodeのスタイル指定が効く
<!DOCTYPE html><!--ESCAPEPROCESS-->

<head>

<script>

function onloadx() {

//一般関数

console.log( "文字列" );

}

function Class1() {

//クラス

console.log( "文字列" );

}

Class1.prototype.method1 = function() {

//メソッド

console.log( "文字列" );

}

</script>

</head>

<body onload="onloadx();" style="">

Hello world!<BR>

</body>

</html>



3.
%%com.webapp.src:/webappsrccheck2.html,/webappsrccheck.html%%
と記述した場合

webapps/src/default.cssのスタイル指定が効く
<!DOCTYPE html><!--ESCAPEPROCESS-->

<head>

<script>

function onloadx() {

//一般関数 コメント変更

console.log( "文字列変更" );

行追加

}

function Class1() {

//クラス コメント変更

console.log( "文字列変更" );

行追加

}

Class1.prototype.method1 = function() {

//メソッド コメント変更

console.log( "文字列変更" );

行追加

}

</script>

</head>

<body onload="onloadx();文字列変更" style="">

Hello world!<BR>

HTML追加

</body>

</html>



4. <code>
%%com.webapp.src:/webappsrccheck2.html,/webappsrccheck.html%%</code>
と記述した場合

このファイルのcodeのスタイル指定が効く
<!DOCTYPE html><!--ESCAPEPROCESS-->

<head>

<script>

function onloadx() {

//一般関数 コメント変更

console.log( "文字列変更" );

行追加

}

function Class1() {

//クラス コメント変更

console.log( "文字列変更" );

行追加

}

Class1.prototype.method1 = function() {

//メソッド コメント変更

console.log( "文字列変更" );

行追加

}

</script>

</head>

<body onload="onloadx();文字列変更" style="">

Hello world!<BR>

HTML追加

</body>

</html>



5. リンクで
src?webappsrccheck.html
と記述した場合

webapps/src/default.cssのスタイル指定が効く
開く

6. リンクで
src?webappsrccheck2.html,webappsrccheck.html
と記述した場合

webapps/src/default.cssのスタイル指定が効く
開く